# Core types derived from Fortran's mod_var and related modules.

module CoreTypes

using ..FLEXINVERT: π, R_earth

"""
    Domain(config::Config)

Holds domain/grid and inversion bookkeeping typically in Fortran's mod_var.
We avoid global mutable state by storing values in this struct and passing it.
"""
Base.@kwdef mutable struct Domain
    # Regional inversion grid definition
    rllx::Float64 = 0.0
    rlly::Float64 = 0.0
    rurx::Float64 = 0.0
    rury::Float64 = 0.0
    rdx::Float64  = 1.0
    rdy::Float64  = 1.0
    nxregrid::Int = 0
    nyregrid::Int = 0
    surface_layer_height::Float64 = 100.0

    # FLEXPART global grid metadata
    global_nxgrid::Int = 0
    global_nygrid::Int = 0
    global_nzgrid::Int = 0
    global_nxshift::Int = 0
    global_lon::Vector{Float64} = Float64[]
    global_lat::Vector{Float64} = Float64[]
    outheight::Vector{Float64} = Float64[]
    trajdays::Int = 0

    # Counts
    nbox::Int = 0          # number of land regions to invert
    nocn::Int = 0          # number of ocean regions (not inverted if inc_ocean=false)

    # Mappings and masks
    nbox_xy::Matrix{Int}    = zeros(Int, 0, 0)   # mapping operator from grid to regions
    lsm_box::Matrix{Int}    = zeros(Int, 0, 0)   # land-sea mask (1 land, 0 ocean)
    lsm::Matrix{Float64}    = zeros(Float64, 0, 0)   # raw land-sea mask values
    area_box::Vector{Float64} = Float64[]        # areas of regions
    area_ocn::Vector{Float64} = Float64[]        # areas of ocean regions (if present)
    reg_lon::Vector{Float64}  = Float64[]        # longitudes of region grid
    reg_lat::Vector{Float64}  = Float64[]        # latitudes of region grid
    hloc::Vector{Float64}     = Float64[]        # local time offset (hours) per region
end

Domain(cfg)::Domain = Domain(; rllx=cfg.w_edge_lon, rlly=cfg.s_edge_lat, rurx=cfg.e_edge_lon,
                               rury=cfg.n_edge_lat, rdx=cfg.xres, rdy=cfg.yres,
                               nxregrid=Int(floor((cfg.e_edge_lon - cfg.w_edge_lon)/cfg.xres)),
                               nyregrid=Int(floor((cfg.n_edge_lat - cfg.s_edge_lat)/cfg.yres)))

end # module
